package com.caijb.netty.bio;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author caijb
 * @version 1.0
 * @data 2025/8/23 14:48
 */
public class BioServer {
    private ServerSocket serverSocket;
    private ExecutorService threadPool;
    private volatile boolean isRunning = true;

    public BioServer(int port) throws IOException {
        // 创建服务端Socket并绑定端口
        serverSocket = new ServerSocket(port);
        // 创建线程池处理客户端连接
        threadPool = Executors.newFixedThreadPool(10);
        System.out.println("BIO Server started on port: " + port);
    }

    public void start() {
        while (isRunning) {
            try {
                // 阻塞等待客户端连接
                Socket clientSocket = serverSocket.accept();
                System.out.println("New client connected: " + clientSocket.getRemoteSocketAddress());

                // 为每个客户端连接创建一个处理线程
                threadPool.execute(new ClientHandler(clientSocket));
            } catch (IOException e) {
                if (isRunning) {
                    System.err.println("Error accepting client connection: " + e.getMessage());
                }
            }
        }
    }

    public void stop() throws IOException {
        isRunning = false;
        if (serverSocket != null && !serverSocket.isClosed()) {
            serverSocket.close();
        }
        if (threadPool != null) {
            threadPool.shutdown();
        }
        System.out.println("Server stopped");
    }

    // 客户端处理线程
    private static class ClientHandler implements Runnable {
        private Socket clientSocket;
        private BufferedReader reader;
        private PrintWriter writer;

        public ClientHandler(Socket socket) {
            this.clientSocket = socket;
        }

        @Override
        public void run() {
            try {
                // 获取输入输出流
                reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                writer = new PrintWriter(clientSocket.getOutputStream(), true);

                // 发送欢迎消息
                writer.println("Welcome to BIO Server! Type 'bye' to exit.");

                String message;
                // 循环读取客户端消息
                while ((message = reader.readLine()) != null) {
                    System.out.println("Received from " + clientSocket.getRemoteSocketAddress() + ": " + message);

                    // 处理退出命令
                    if ("bye".equalsIgnoreCase(message.trim())) {
                        writer.println("Goodbye!");
                        break;
                    }

                    // 回显消息给客户端
                    writer.println("Echo: " + message);
                }
            } catch (IOException e) {
                System.err.println("Error handling client: " + e.getMessage());
            } finally {
                closeResources();
            }
        }

        private void closeResources() {
            try {
                if (reader != null) reader.close();
                if (writer != null) writer.close();
                if (clientSocket != null) clientSocket.close();
                System.out.println("Client disconnected: " + clientSocket.getRemoteSocketAddress());
            } catch (IOException e) {
                System.err.println("Error closing resources: " + e.getMessage());
            }
        }
    }

    public static void main(String[] args) {
        try {
            BioServer server = new BioServer(8080);
            // 添加关闭钩子，优雅关闭服务器
            Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                try {
                    server.stop();
                } catch (IOException e) {
                    System.err.println("Error stopping server: " + e.getMessage());
                }
            }));
            server.start();
        } catch (IOException e) {
            System.err.println("Failed to start server: " + e.getMessage());
        }
    }
}
